package exp07gui.tictactoe2;

import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;

public class TicTacToe extends JFrame implements ActionListener {
	static Random random = new Random();

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	public static void main(String[] args) {
		new TicTacToe();
	}

	final static String X = "X";
	final static String O = "O";
	final static String E = " ";
	final static int EE = 2;
	final static int XX = 0;
	final static int OO = 1;
	int computer;
	int player;
	int turn = 0;
	int B[][] = new int[3][3];
	JButton[] btn = new JButton[9];

	public TicTacToe() {
		turn = 0;
		player = turn;
		computer = 1 - turn;
		this.setLayout(new GridLayout(3, 3));
		for (int i = 0; i < 9; i++) {
			this.add(btn[i] = new JButton());
			btn[i].addActionListener(this);
		}
		for (int i = 0; i < 9; i++)
			B[i / 3][i % 3] = EE;
		this.setSize(300, 300);
		this.setVisible(true);

	}

	@Override
	public void actionPerformed(ActionEvent e) {

		for (int i = 0; i < 9; i++) {
			if (e.getSource() == btn[i]) {

				btn[i].setText("X");

				B[i / 3][i % 3] = player;

				btn[i].setEnabled(false);

				if (checkWin(OO)) {
					JOptionPane.showMessageDialog(null, "O Win!");
					resetGame();
					return;

				} else if (checkWin(XX)) {
					JOptionPane.showMessageDialog(null, "X Win!");
					resetGame();
					return;

				} else if (checkEnd()) {
					JOptionPane.showMessageDialog(null, "Draw");
					resetGame();
					return;
				}
				//computerRun();
				greedySearch();
				break;
			}
		}
	}

	private boolean checkEnd() {
		for (int i = 0; i < 9; i++)
			if (B[i / 3][i % 3] == EE)
				return false;
		return true;
	}

	private void computerRun() {

		int x, y;
		while (true) {
			x = random.nextInt(3);
			y = random.nextInt(3);
			if (B[x][y] == EE) {
				break;
			}
		}
		B[x][y] = computer;
		btn[x * 3 + y].setText("O");
		btn[x * 3 + y].setEnabled(false);

	}

	private void greedySearch() {

		int x = 0, y = 0, maxValue = Integer.MIN_VALUE;
		for (int i = 0; i < 3; i++)
			for (int j = 0; j < 3; j++) {
				if (fvalue(i, j) > maxValue) {
					x = i;
					y = j;
					maxValue = fvalue(i, j);
				}
			}
		JOptionPane.showMessageDialog(null, String.format("%d %d %d", x,y,maxValue));
		B[x][y] = computer;
		btn[x * 3 + y].setText("O");
		btn[x * 3 + y].setEnabled(false);

	}

	private int fvalue(int x, int y) {
		if(B[x][y]!=EE)
			return -1;
		if (canWin(x, y, computer))
			return Integer.MAX_VALUE;
		if (canWin(x, y, player))
			return 50000;
		int s = 0;
		if (x == 1 && y == 1)
			s += 2000;
		if (x == y)
			s += 1000;
		if (x + y == 2)
			s += 1000;
		return s;
	}

	private boolean canWin(int x, int y, int p) {
		B[x][y] = p;
		if (checkWin(p)) {
			B[x][y] = EE;
			return true;
		} else {
			B[x][y] = EE;

			return false;
		}
	}

	private void resetGame() {
		for (int i = 0; i < 9; i++) {
			B[i / 3][i % 3] = EE;
			btn[i].setText(E);
			btn[i].setEnabled(true);

		}

	}

	private boolean checkWin(int x) {
		for (int i = 0; i < 3; i++)
			if (B[i][0] == x && B[i][1] == x && B[i][2] == x)
				return true;
		for (int i = 0; i < 3; i++)
			if (B[0][i] == x && B[1][i] == x && B[2][i] == x)
				return true;
		if (B[0][0] == x && B[1][1] == x && B[2][2] == x)
			return true;
		return B[0][2] == x && B[1][1] == x && B[2][0] == x;

	}

}
